﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bamboo.Utils
{
    public abstract class AsyncWorkBase
    {
        public IAsyncResult Result = null;

        public string Title = "";

        public Exception Error = null;

        public StringBuilder Output = new StringBuilder(16 * 1024);

        protected abstract void ThreadExecute();

        public void Start()
        {
            var action = new Action(() => { 
                try
                {
                    ThreadExecute();
                }
                catch (Exception ex)
                {
                    Error = ex;
                }
            });
            this.Result = action.BeginInvoke(null, null);
        }

        public string GetDebugText()
        {
            var s = new StringBuilder(16*1024);
            s.AppendLine("任务：" + Title);
            if (Error != null)
            {
                s.AppendLine("错误：" + Error.ToString());
            }
            if (Output.Length > 0)
            {
                s.AppendLine("输出：" + Output.ToString());
            }
            return s.ToString();
        }

    }

    public class AsyncWorkCollection<T>
        where T: AsyncWorkBase
    {
        public List<T> Items = new List<T>();
        public void Add(T work)
        {
            Items.Add(work);
        }

        public void WaitForAll()
        {
            foreach (var item in Items)
            {
                item.Result.AsyncWaitHandle.WaitOne();
            }
        }

        public int GetFailCount()
        {
            int fail = 0;
            foreach (var item in Items)
            {
                if (item.Error != null) ++fail;
            }
            return fail;
        }

        public string GetSummaryText()
        {
            int succ = 0;
            int fail = 0;
            foreach (var item in Items)
            {
                if (item.Error == null) ++succ;
                else ++fail;
            }
            return "合计执行任务：" + Items.Count + "，成功：" + succ + "，失败：" + fail;
        }

        public string GetDetailText()
        {
            var s = new StringBuilder(128 * 1024);
            foreach (var item in Items)
            {
                if (item.Error != null || item.Output.Length > 0)
                {
                    s.AppendLine(item.GetDebugText().Trim());
                }
            }
            return s.ToString();
        }
    }
}
